/**
  ******************************************************************************
  * @file    mg_ble_control.h
  * @author  
  * @version V0.1
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2021 Shanghai Macrogiga Electronics</center></h2>
  *
  ******************************************************************************
  */
#ifndef __MG_BLE_CONTROL_H__
#define __MG_BLE_CONTROL_H__


//GAP  AD_TYPE
#define BLE_GAP_AD_TYPE_FLAGS                               0x01 /**< Flags for discoverability. */
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE   0x02 /**< Partial list of 16 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE         0x03 /**< Complete list of 16 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE   0x04 /**< Partial list of 32 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE         0x05 /**< Complete list of 32 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE  0x06 /**< Partial list of 128 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE        0x07 /**< Complete list of 128 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME                    0x08 /**< Short local device name. */
#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME                 0x09 /**< Complete local device name. */
#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL                      0x0A /**< Transmit power level. */
#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE                     0x0D /**< Class of device. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C               0x0E /**< Simple Pairing Hash C. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R         0x0F /**< Simple Pairing Randomizer R. */
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE           0x10 /**< Security Manager TK Value. */
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS          0x11 /**< Security Manager Out Of Band Flags. */
#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE     0x12 /**< Slave Connection Interval Range. */
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT       0x14 /**< List of 16-bit Service Solicitation UUIDs. */
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT      0x15 /**< List of 128-bit Service Solicitation UUIDs. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA                        0x16 /**< Service Data - 16-bit UUID. */
#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS               0x17 /**< Public Target Address. */
#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS               0x18 /**< Random Target Address. */
#define BLE_GAP_AD_TYPE_APPEARANCE                          0x19 /**< Appearance. */
#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL                0x1A /**< Advertising Interval. */
#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS         0x1B /**< LE Bluetooth Device Address. */
#define BLE_GAP_AD_TYPE_LE_ROLE                             0x1C /**< LE Role. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256            0x1D /**< Simple Pairing Hash C-256. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256      0x1E /**< Simple Pairing Randomizer R-256. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID             0x20 /**< Service Data - 32-bit UUID. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID            0x21 /**< Service Data - 128-bit UUID. */
#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA                 0x3D /**< 3D Information Data. */
#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA          0xFF /**< Manufacturer Specific Data. */

#define GAP_ADTYPE_FLAGS_LIMITED                            0x01 //!< Discovery Mode: LE Limited Discoverable Mode
#define GAP_ADTYPE_FLAGS_GENERAL                            0x02 //!< Discovery Mode: LE General Discoverable Mode
#define GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED                0x04 //!< Discovery Mode: BR/EDR Not Supported

#define ADV_IND            0
#define ADV_DIRECT_IND     1
#define ADV_NONCONN_IND    2
#define ADV_SCAN_REQ       3
#define ADV_SCAN_RSP       4
#define ADV_CONN_REQ       5
#define ADV_SCAN_IND       6

#define ADDR_TYPE_PUBLIC  0x00
#define ADDR_TYPE_RANDOM  0x01
//#define ADV_HDR_TYPE_PUBLIC 0x00

#define ATT_ERROR_RSP                            0x01
#define ATT_EXCHANGE_MTU_REQ                     0x02
#define ATT_EXCHANGE_MTU_RSP                     0x03 
#define ATT_FIND_INFO_REQ                          0x04
#define ATT_FIND_INFO_RSP                          0x05
#define ATT_FIND_BY_TYP_REQ                      0x06
#define ATT_FIND_BY_TYP_RSP                      0x07
#define ATT_RD_BY_TYPE_REQ                       0x08
#define ATT_RD_BY_TYPE_RSP                       0x09
#define ATT_RD_REQ                               0x0A
#define ATT_READ_RSP                             0x0B
#define ATT_READ_BLOB_REQ                        0x0C
#define ATT_READ_BLOB_RSP                        0x0D
#define ATT_READ_MULTI_REQ                       0x0E
#define ATT_READ_MULTI_RSP                       0x0F
#define ATT_RD_BY_GROUP_TYPE_REQ                 0x10
#define ATT_RD_BY_GROUP_TYPE_RSP                 0x11
///att server opcode code
#define ATT_WR_REQ                               0x12
#define ATT_WR_RSP                               0x13
#define ATT_PREPARE_WR_REQ                       0x16
#define ATT_PREPARE_WR_RSP                       0x17
#define ATT_EXECUTE_WR_REQ                       0x18
#define ATT_EXECUTE_WR_RSP                       0x19
#define ATT_NOTIFY_HANDLE                        0x1B
#define ATT_INDICATION_HANDLE                    0x1D
#define ATT_CFM_HANDLE                           0x1E
#define ATT_WR_CMD                               0x52
#define ATT_SIGNED_WR_CMD                        0xD2

/// ATT Error Codes
#define ATT_ERR_INVALID_HANDLE                   0x01
#define ATT_ERR_READ_NOT_PERMITTED               0x02
#define ATT_ERR_WRITE_NOT_PERMITTED              0x03
#define ATT_ERR_INVALID_PDU                      0x04
#define ATT_ERR_INSUFFICIENT_AUTHEN              0x05
#define ATT_ERR_UNSUPPORTED_REQ                  0x06
#define ATT_ERR_INVALID_OFFSET                   0x07
#define ATT_ERR_INSUFFICIENT_AUTHOR              0x08
#define ATT_ERR_PREPARE_QUEUE_FULL               0x09
#define ATT_ERR_ATTR_NOT_FOUND                   0x0a
#define ATT_ERR_ATTR_NOT_LONG                    0x0b
#define ATT_ERR_INSUFFICIENT_KEY_SIZE            0x0c
#define ATT_ERR_INVALID_VALUE_SIZE               0x0d
#define ATT_ERR_UNLIKELY                         0x0e
#define ATT_ERR_INSUFFICIENT_ENCRYPT             0x0f
#define ATT_ERR_UNSUPPORTED_GRP_TYPE             0x10
#define ATT_ERR_INSUFFICIENT_RESOURCES           0x11

/// Characteristic Properties Bit
#define ATT_CHAR_PROP_RD                            0x02
#define ATT_CHAR_PROP_W_NORSP                       0x04
#define ATT_CHAR_PROP_W                             0x08
#define ATT_CHAR_PROP_NTF                           0x10
#define ATT_CHAR_PROP_IND                           0x20 

/*----------------- DESCRIPTORS -----------------*/
//#define GATT_CHAR_EXT_PROPS_UUID       0x2900
#define TYPE_INC       0x2802
#define TYPE_CHAR      0x2803
#define TYPE_INFO      0x2901
#define TYPE_CFG       0x2902
#define TYPE_xRpRef    0x2907
#define TYPE_RpRef     0x2908

/// Common 16-bit Universal Unique Identifier
enum {
    ATT_INVALID_UUID =                             0,

/*------------------- UNITS ---------------------*/
    /// No defined unit
    ATT_UNIT_UNITLESS                       = 0x2700,

/*---------------- DECLARATIONS -----------------*/
    /// Primary service Declaration
    GATT_PRIMARY_SERVICE_UUID             = 0x2800,
    GATT_SECONDARY_SERVICE_UUID           = 0x2801,
    /// Characteristic Declaration
    GATT_CHARACTER_UUID                   = 0x2803,
    ATT_RD_SVC_UUID                       = 0x2804,
    ATT_NOTIFY_VALUE_HD                   = 0x2805,

    /*----------------- DESCRIPTORS -----------------*/
    /// Characteristic extended properties
    GATT_CHAR_EXT_PROPS_UUID                = 0x2900,
    /// Characteristic user description
    ATT_DESC_CHAR_USER_DESCRIPTION,
    /// Client characteristic configuration
    ATT_DESC_CLIENT_CHAR_CFG,
    /// Server characteristic configuration
    ATT_DESC_SERVER_CHAR_CFG,
    /// Characteristic Presentation Format
    ATT_DESC_CHAR_PRES_FORMAT,
    /// Characteristic Aggregate Format
    ATT_DESC_CHAR_AGGREGATE_FORMAT,
    /// Valid Range
    ATT_DESC_VALID_RANGE,
    /// External Report Reference
    ATT_DESC_EXT_REPORT_REF,
    /// Report Reference
    ATT_DESC_REPORT_REF,


    /*--------------- CHARACTERISTICS ---------------*/
/// Device name
    DEVICE_NAME_UUID                        = 0x2A00,
    /// Last define
    ATT_LAST
};

#define PERIPH_CONNECT_DISCONNECTED       0x00  /*connection lost*/
#define PERIPH_CONNECT_CONNECTED          0x01  /*connection success*/
#define PERIPH_CONNECT_PAIRED             0x40  /*pairing done, now one can invoke function u8* GetLTKInfo(u8* newFlag)*/
#define PERIPH_CONNECT_INTERVAL_UPDATE_ACC 0x80 /*sig connection interval update cmd accepted*/
#define PERIPH_CONNECT_INTERVAL_UPDATE_REJ 0x81 /*sig connection interval update cmd rejected*/
//#define CENTRAL_CONNECT_CONNECTED       0x02  /*connection success*/
//#define CENTRAL_CONNECT_ATTEMPT_FAILED  0x03  /*try connection failed after NN attempts*/
//#define CENTRAL_CONNECT_DISCONNECTED    0x04  /*connection lost*/

u8* MgBle_GetBleStackVersion(void); //returns string value of [FV_BT_V5_X.X.X]
u8* GetFirmwareInfo(void);          //such as "FVxx.5.0.0"

typedef struct _tagBleAdvDataInfo{
    u32 interval;    //unit = 0.625 ms

    u8  txAddrType;  //adv ind addr type 0(public) or 1(random)
    u8  advType;     //ADV_IND, ADV_NONCONN_IND
    u8  advDataLen;
    u8  scanResponseDataLen;
    
    u8  *advData;
    u8  *scanResponseData;
    
    u8  directIndTargetAddr[6];
    u8  directIndTargetAddrType; //0(public) or 1(random)
}BLE_ADV_DATA_INFO;


typedef void (*callback)(u8 evt, u8* dat);

#define TXPWR_0DBM    0x03  /* 0dBm*/
#define TXPWR__6DBM   0x02  /*-6dBm*/
#define TXPWR__12DBM  0x01  /*-12dBm*/
#define TXPWR__18DBM  0x00  /*-18dBm*/

u8   MgBle_Init(u8 txpwr, u8**addr); //returns IcVersion 0x5X

void MgBle_Periph_Init(BLE_ADV_DATA_INFO *slave_cfg);
u8   MgBle_Periph_Run(callback); //one step, return 1 means end of connection
void MgBle_Periph_Disconnect(void);

void MgBle_SetLePinCode(u8 *PinCode/*6 0~9 digitals*/);

//this function is to enable/disable pairing
//Parameters: enable_flag - 0 to reject pairing, 1 to allow pairing. Allow pairing by default
//return: None
void ble_set_slave_pairing_en_flag(u8 enable_flag);

//Function: MgBle_SetAdvEnable
//this function is to enable/disable ble adv
//Parameters: sEnableFlag - 0 to disable adv, 1 to enable adv. Adv enabled by default.
//return: None
void MgBle_SetAdvEnable(su8 flag);
u8   MgBle_GetAdvEnable(void);

void MgBle_Periph_Update_Adv_Data(u8 *adv_data, u8 len);
void MgBle_Periph_Update_Adv_Rsp_Data(u8 *rsp_data, u8 len);
void MgBle_Periph_Update_Adv_Type(u8 type/*0-adv_ind, 2-adv_nonconn_ind, 0x40 - RANDOM, 0x00 - PUBLIC*/);
void MgBle_Periph_Update_Adv_Interval(u16 interval/*unit 0.625ms*/);
//u8 radio_getRssi(void); /*this function is defined in file "mg_driver_ble.h" */

//Get current (or the latest) connected master device's MAC
//returns mac(6 Bytes, Little-Endian format) and the type(MacType, 0 means public type, others mean random type)
u8* GetMasterDeviceMac(u8* MacType);

void MgBle_ConnStatusUpdate(u8 status /*PERIPH_CONNECT_XXXXX*/); //connect status callback, porting function

void MgBle_SetAncsEnableFlag(u8 enableFlag); //default is disabled
u8   ANCS_Discover(void); //start the ANCS discover, returns 0 if not start correctly(should be in paired condition).

void MgBle_SetBleAddr(u8* addr, u8 addr_type/*no use*/);

u16 MgBle_SconnGetConnInterval(void); //current used interval in the unit of 1.25ms
void SIG_ConnParaUpdateReq(u16 IntervalMin, u16 IntervalMax, u16 slaveLateny, u16 TimeoutMultiplier);

///////////////////////////test/debug APIs/////////////////////////////////
void MgBle_SetFixAdvChannel(u8 isFixCh37Flag); //slave role usage ONLY!!!

void MgBle_EnableDirectTestMode(void); //enable direct test mode cfg

void MgBle_SetRfCal(u8 nCounter/*unit: 1 interval, default is 17.  0 means disabled*/);

///------------------------------------------------------------------------------------------------------------------------
void ble_set_llLongPktTxRxOcters(u8 LongPktSize);
void ble_set_gatt_mtu(u8 mtu_max);
//25 <= len <= LongPktMaxTxOctets - 7
u8   sconn_notifyLongPktData(u16 handle,u8* data, u8 len); //returns 1 means OK.
u8   sconn_indicationLongPktData(u16 handle,u8* data, u8 len);//returns 1 means OK.
////27 <= len <= LongPktMaxTxOctets - 5
u8   att_server_rdLongPktData(u8*data, u8 len);//returns 1 means OK.

u8   is_att_LongPktDataEnabled(void); //1 means long package data transfering feature is now enabled.

u8   att_get_sconn_notifyLongPktMinSize(void);//25
u8   att_get_sconn_notifyLongPktMaxSize(void);//shall be invoked after [att_exMtuReq()]. less than 25, long pkt is not ready.
u8   att_get_sconn_indicationLongPktMinSize(void);//25
u8   att_get_sconn_indicationLongPktMaxSize(void);//shall be invoked after [att_exMtuReq()]. less than 25, long pkt is not ready.
u8   att_get_att_server_rdLongPktMinSize(void);//27
u8   att_get_att_server_rdLongPktMaxSize(void);//shall be invoked after [att_exMtuReq()]. less than 27, long pkt is not ready.
///------------------------------------------------------------------------------------------------------------------------

u8   sconn_notifydata(u8* data, u8 len);//returns data size has been sent. 
u8   sconn_indicationdata(u8* data, u8 len);
void set_notifyhandle(u16 hd);//set notify/indication handle

extern u8 LongPktMaxTxOctets;

void att_ErrorFd_eCode(u8 pdu_type, u8 attOpcode, u16 attHd, u8 errorCode);

u8 gatt_notifydata(u16 Handle,u8* Buf, u8 Len);    //returns bytes send,long or short package supported.
u8 gatt_indicationdata(u16 Handle,u8* Buf, u8 Len);//returns bytes send,long or short package supported.
void gatt_read_rsp(u8 pdu_type, u8 attOpcode, u16 att_hd, u8* attValue, u8 datalen);//long or short package supported

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void radio_startCarrierTone(u8 ble_channel);
void radio_endCarrierTone(void);
#endif

